package com.sunlands.deskmate.message.handler.dispatcher.impl;

import com.sunlands.deskmate.channel.ChannelInfo;
import com.sunlands.deskmate.channel.ChannelManager;
import com.sunlands.deskmate.channel.WebSocketServerHandler;
import com.sunlands.deskmate.message.entity.Messages;
import com.sunlands.deskmate.message.handler.dispatcher.Dispatcher;
import com.sunlands.deskmate.message.handler.storager.unsync.UnsyncMessageStorager;
import com.sunlands.deskmate.service.DialogRecordServiceImpl;
import com.sunlands.deskmate.utils.IdGenerator;
import lombok.extern.slf4j.Slf4j;
import org.redisson.api.RMapCache;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import java.util.Objects;
import java.util.Set;
import static com.sunlands.deskmate.config.RabbitMqConfig.EVENT_EXCHANGE_LOOKUP;

/**
 * 房间消息全部通过socket发送，没有离线消息
 */
@Slf4j
@Component
public class LiveRoomCloseDispatcher implements Dispatcher {

    @Autowired
    private DialogRecordServiceImpl dialogRecordService;

    @Autowired
    private UnsyncMessageStorager unsyncMessageStorager;

    @Autowired
    private RabbitTemplate rabbitTemplate;


    @Override
    public void dispatcher(Messages messages) {

        String roomId = messages.getToId();
        String key = WebSocketServerHandler.getRoomKey(messages.getType(), roomId);
        Set<Long> members = dialogRecordService.refreshMembers(key);
        RMapCache<String, ChannelInfo> redisChannelStore = ChannelManager.getRedisChannelStore();

        if (Objects.isNull(members) || members.isEmpty()) {
            log.info("房间会话中用户为空，房间已经关闭，不发送消息 key = {} message = {}", key, messages);
            return;
        }

        Long oldAckId = messages.getAckId();
        messages.setAckId(IdGenerator.id());
        log.info("1.2 防止消息乱序，将消息进行转换 重新生成ackId oldAckId = {} newAckId = {}", oldAckId, messages.getAckId());
        for (Object userId : members) {
            messages.setRealToId(Long.parseLong(userId.toString()));
            //关闭房间消息，不发送给自己
            if (messages.getRealToId().toString().equals(messages.getFromUserId())) {
                continue;
            }
//            messages.setAckId(IdGenerator.id());
            ChannelInfo channelInfo = new ChannelInfo(messages.getRealToId());
            boolean success = unsyncMessageStorager.add(channelInfo.getSessionKey(), messages, messages.getAckId());

            if (success) {
                ChannelInfo info = redisChannelStore.get(channelInfo.getSessionKey());
                //通道信息为空的话，不通知发送消息，再次连上通道后会重新发送
                if (Objects.nonNull(info)) {
                    log.info("2、房间消息  转为新的消息 条数 members = {} msgEntity = {},", members.size(), messages);
                    rabbitTemplate.convertAndSend(EVENT_EXCHANGE_LOOKUP, info.getWorkId().toString(), messages);
                }
            }

        }

        if (Objects.nonNull(members) && !members.isEmpty()) {
            dialogRecordService.remove(key);
        }
    }
}
